#ifndef __OBJIMPORTER_H__
#define __OBJIMPORTER_H__

#include "../FileServer/FileServer.h"

#include <fstream>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <list>
#include <map>
#include <assert.h>

// This program imports .obj model and the material file .mtl
// Most parts of the codes. come from rcssserver3d

class Vector3f
{
public:
	Vector3f()
	{
		m_x = 0.0;
		m_y = 0.0;
		m_z = 0.0;

	}

	Vector3f( double _x, double _y, double _z )
	{
		m_x = _x;
		m_y = _y;
		m_z = _z;
	}

	double x() { return m_x;}
	double y() { return m_y;}
	double z() { return m_z;}

private:
	double m_x;
	double m_y;
	double m_z;
};

struct ObjMatValues
{
	std::string name;
	float ambient[4];
	float diffuse[4];
	float specular[4];
	float shininess;
	float alpha;
	std::string diffuseTexture;
};

struct VTNIndex
{
	unsigned int v;  // vertex index
	unsigned int vt; // texture coord index
	unsigned int vn; // normal index
};

struct FaceIndex
{
	VTNIndex vertex[3];
};

typedef std::vector<Vector3f>                 TVector3fVector;
typedef std::vector<ObjMatValues>             TObjMatValueVector;
typedef std::list<FaceIndex>                  TFaceIndexList;
typedef std::map<std::string, TFaceIndexList> TMatNameFaceIndexListMap;

class ObjImporter
{
public:
	ObjImporter();
	~ObjImporter();

	bool ImportObj( const std::string& file_name );
	void Test();

	const TVector3fVector& PosVec() const { return m_PosVec; }
	const TVector3fVector& TexVec() const { return m_TexVec; }
	const TVector3fVector& NormVec() const { return m_NormVec; }
	const TObjMatValueVector& MatVec() const { return m_Mats; }
	const TFaceIndexList& FaceList() const { return m_Faces; }
	const TMatNameFaceIndexListMap& MatNameFaceIndexListMap() const { return m_MatNameFaceIndexListMap; }

	Vector3f Pos( const FaceIndex& face, unsigned int ver_idx ) const;
	bool Norm( const FaceIndex& face, unsigned int ver_idx, Vector3f& n ) const;
	bool TexCoor( const FaceIndex& face, unsigned int ver_idx, Vector3f& t ) const;
	bool FindMat( const std::string& mat_name, ObjMatValues& new_mat );
	const TFaceIndexList& MatFaceIndexList( const std::string &mat_name );

private:
	TVector3fVector			 m_PosVec;
	TVector3fVector			 m_TexVec;
	TVector3fVector			 m_NormVec;
	TObjMatValueVector       m_Mats;
	TFaceIndexList           m_Faces;
	TMatNameFaceIndexListMap m_MatNameFaceIndexListMap;

	void ExplodeString(std::string & input, 
		std::vector<std::string> & output, 
		std::string & del);

	bool SetupMaterials(std::string & matLibName, 
		TObjMatValueVector & matVector); 
};


#endif //__OBJIMPORTER_H__